package com.csun.cmny.provider.service.impl;

import com.csun.cmny.base.dto.LoginAuthDto;
import com.csun.cmny.base.enums.ErrorCodeEnum;
import com.csun.cmny.core.support.BaseService;
import com.csun.cmny.provider.dao.DmcCsunHumidistatLocationMapper;
import com.csun.cmny.provider.device.csun.gateway.GatewayMessageSender;
import com.csun.cmny.provider.exceptions.DmcBizException;
import com.csun.cmny.provider.model.constant.DeviceConstant;
import com.csun.cmny.provider.model.constant.LifeConstant;
import com.csun.cmny.provider.model.domain.*;
import com.csun.cmny.provider.model.dto.humidistat.BindCsunHumidistatLocationDto;
import com.csun.cmny.provider.model.dto.humidistat.CsunHumidistatQueryDto;
import com.csun.cmny.provider.model.dto.propertyManagement.SelectDeviceDataDto;
import com.csun.cmny.provider.model.enums.device.DeviceStatusEnum;
import com.csun.cmny.provider.model.enums.device.DmcDeviceTypeEnum;
import com.csun.cmny.provider.model.vo.HumidistatReqVo;
import com.csun.cmny.provider.model.vo.RoomBuildingVo;
import com.csun.cmny.provider.model.vo.humidistat.CsunHumidistatVo;
import com.csun.cmny.provider.model.vo.life.DmcDeviceByRoom;
import com.csun.cmny.provider.model.vo.life.lifeRoomHumidistat;
import com.csun.cmny.provider.model.vo.propertyManagement.PropertyDataVo;
import com.csun.cmny.provider.service.*;
import com.csun.cmny.util.PublicUtil;
import com.csun.cmny.util.RedisKeyUtil;
import com.github.pagehelper.PageHelper;
import com.xiaoleilu.hutool.util.BeanUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.context.annotation.Bean;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;

/**
 * @Auther: chisj chisj@foxmal.com
 * @Date: 2019-12-27 15:19
 * @Description:
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class DmcCsunHumidistatLocationServiceImpl extends BaseService<DmcCsunHumidistatLocation>
        implements DmcCsunHumidistatLocationService {

    @Resource
    private DmcCsunHumidistatLocationMapper dmcCsunHumidistatLocationMapper;
    @Resource
    private DmcDeviceService dmcDeviceService;
    @Resource
    private DmcCsunHumidistatThresholdService dmcCsunHumidistatThresholdService;
    @Resource
    private DmcCsunHumidistatConfigService dmcCsunHumidistatConfigService;
    @Resource
    private DmcDeviceAlertService dmcDeviceAlertService;
    @Resource
    private GatewayMessageSender gatewayMessageSender;
    @Resource
    private DmcCsunGatewayConfigHumidistatService dmcCsunGatewayConfigHumidistatService;
    @Resource
    private DmcCsunGatewayBindService dmcCsunGatewayBindService;
    @Resource
    private DmcCsunHumidistatDataService dmcCsunHumidistatDataService;
    @Resource
    private DmcCsunHumidistatDataHiService dmcCsunHumidistatDataHiService;
    @Resource
    private RedisTemplate redisTemplate;

    /**
     * query dmc csun humidistat and location list with page
     *
     * @param csunHumidistatQueryDto the csun humidistat query dto
     * @return the list
     */
    @Override
    public List<CsunHumidistatVo> queryListWithPage(CsunHumidistatQueryDto csunHumidistatQueryDto) {

        PageHelper.startPage(csunHumidistatQueryDto.getPageNum(), csunHumidistatQueryDto.getPageSize());

        return dmcCsunHumidistatLocationMapper.queryListWithPage(csunHumidistatQueryDto);
    }

    /**
     * delete dmc csun humidistat by id
     *
     * @param id the csun humidistat id
     * @return the int.
     */
    @Override
    public Integer deleteById(Long id) {

        // 判断是否在使用中
        DmcCsunHumidistatLocation dmcCsunHumidistatLocation = dmcCsunHumidistatLocationMapper.selectByPrimaryKey(id);
        if (PublicUtil.isNotEmpty(dmcCsunHumidistatLocation)) {
            // TODO 正在使用中, 无法删除
            throw new DmcBizException(ErrorCodeEnum.DMC100614001);
        }

        // 判断是绑定了网关
        DmcCsunGatewayBind dmcCsunGatewayBind = new DmcCsunGatewayBind();
        dmcCsunGatewayBind.setDeviceId(id);
        int count = dmcCsunGatewayBindService.selectCount(dmcCsunGatewayBind);
        if (count > 0) {
            throw new DmcBizException(ErrorCodeEnum.DMC100614009);
        }

        dmcCsunHumidistatLocationMapper.deleteByPrimaryKey(id);

        return dmcDeviceService.deleteDmcDeviceById(id);
    }

    /**
     * bind dmc csun humidistat and location
     *
     * @param bindCsunHumidistatLocationDto the bind csun humidistat location
     * @param loginAuthDto                  the login auth dto
     * @return the int
     */
    @Override
    public Integer bind(BindCsunHumidistatLocationDto bindCsunHumidistatLocationDto, LoginAuthDto loginAuthDto) {

        // 判断设备是否存在

        // 判断设备是否已经绑定过
        DmcCsunHumidistatLocation dmcCsunHumidistatLocationQuery =
                dmcCsunHumidistatLocationMapper.selectByPrimaryKey(bindCsunHumidistatLocationDto.getDeviceId());
        if (PublicUtil.isNotEmpty(dmcCsunHumidistatLocationQuery)) {
            // 温湿度传感器已经绑定
            throw new DmcBizException(ErrorCodeEnum.DMC100614002);
        }

        // TODO 校验绑定方式
        switch (bindCsunHumidistatLocationDto.getBindType()) {
            case DeviceConstant.DEVICE_BIND_TYPE_CUSTOM:

                // 删除已经下发的配置
                DmcCsunGatewayConfigHumidistat configCustom = new DmcCsunGatewayConfigHumidistat();
                configCustom.setDeviceId(bindCsunHumidistatLocationDto.getDeviceId());
                dmcCsunGatewayConfigHumidistatService.delete(configCustom);

                // 根据房间，机构Id获取配置，设置到设备中
                DmcCsunHumidistatConfig dmcCsunHumidistatConfigCustom = dmcCsunHumidistatConfigService
                        .queryConfigByRoomIdAndGroupId(0, loginAuthDto.getGroupId());

                // 发送配置
                if (PublicUtil.isNotEmpty(dmcCsunHumidistatConfigCustom)) {

                    // 保存或更新设备配置
                    dmcCsunHumidistatConfigCustom.setDeviceId(bindCsunHumidistatLocationDto.getDeviceId());
                    dmcCsunHumidistatConfigCustom.setIsSend(LifeConstant.DEVICE_ORDER_NEED_SEND);
                    dmcCsunHumidistatConfigCustom.setCreator(loginAuthDto.getUserName());
                    dmcCsunHumidistatConfigCustom.setCreatorId(loginAuthDto.getUserId());
                    dmcCsunHumidistatConfigCustom.setLastOperator(loginAuthDto.getUserName());
                    dmcCsunHumidistatConfigCustom.setLastOperatorId(loginAuthDto.getUserId());
                    dmcCsunHumidistatConfigService.saveOrUpdate(dmcCsunHumidistatConfigCustom);

                    gatewayMessageSender.setHumidistatTimer(bindCsunHumidistatLocationDto.getDeviceId(),
                            dmcCsunHumidistatConfigCustom.getTemperatureMeasuringTimeInterval());
                }
                break;

            case DeviceConstant.DEVICE_BIND_TYPE_ROOM:

                // 删除已经下发的配置
                DmcCsunGatewayConfigHumidistat config = new DmcCsunGatewayConfigHumidistat();
                config.setDeviceId(bindCsunHumidistatLocationDto.getDeviceId());
                dmcCsunGatewayConfigHumidistatService.delete(config);

                // 根据房间，机构Id获取配置，设置到设备中
                DmcCsunHumidistatConfig dmcCsunHumidistatConfig = dmcCsunHumidistatConfigService
                        .queryConfigByRoomIdAndGroupId(bindCsunHumidistatLocationDto.getRoomId(), loginAuthDto.getGroupId());

                // 发送配置
                if (PublicUtil.isNotEmpty(dmcCsunHumidistatConfig)) {

                    // 保存或更新设备配置
                    dmcCsunHumidistatConfig.setDeviceId(bindCsunHumidistatLocationDto.getDeviceId());
                    dmcCsunHumidistatConfig.setIsSend(LifeConstant.DEVICE_ORDER_NEED_SEND);
                    dmcCsunHumidistatConfig.setCreator(loginAuthDto.getUserName());
                    dmcCsunHumidistatConfig.setCreatorId(loginAuthDto.getUserId());
                    dmcCsunHumidistatConfig.setLastOperator(loginAuthDto.getUserName());
                    dmcCsunHumidistatConfig.setLastOperatorId(loginAuthDto.getUserId());
                    dmcCsunHumidistatConfigService.saveOrUpdate(dmcCsunHumidistatConfig);

                    gatewayMessageSender.setHumidistatTimer(bindCsunHumidistatLocationDto.getDeviceId(),
                            dmcCsunHumidistatConfig.getTemperatureMeasuringTimeInterval());
                }

                break;
            case DeviceConstant.DEVICE_BIND_TYPE_LIFE:
                /**
                 * @date 2019-01-07
                 * @author chisj
                 * @desc 一个房间只能绑定一个温湿度计
                 */
                dmcCsunHumidistatLocationQuery = new DmcCsunHumidistatLocation();
                dmcCsunHumidistatLocationQuery.setBindType(DeviceConstant.DEVICE_BIND_TYPE_LIFE);
                dmcCsunHumidistatLocationQuery.setRoomId(bindCsunHumidistatLocationDto.getRoomId());
                int count = dmcCsunHumidistatLocationMapper.selectCount(dmcCsunHumidistatLocationQuery);
                if (count > 0) {
                    throw new DmcBizException(ErrorCodeEnum.DMC100614006);
                }

                // 删除已经下发的配置
                DmcCsunGatewayConfigHumidistat dmcCsunGatewayConfigHumidistat = new DmcCsunGatewayConfigHumidistat();
                dmcCsunGatewayConfigHumidistat.setDeviceId(bindCsunHumidistatLocationDto.getDeviceId());
                dmcCsunGatewayConfigHumidistatService.delete(dmcCsunGatewayConfigHumidistat);

                // 查询配置
//                DmcCsunHumidistatConfig dmcCsunHumidistatConfig = dmcCsunHumidistatConfigService
//                        .queryConfigByDeviceId(bindCsunHumidistatLocationDto.getDeviceId());
                // TODO 设置配置

                // 根据房间，机构Id获取配置，设置到设备中
                DmcCsunHumidistatConfig csunHumidistatConfig = dmcCsunHumidistatConfigService
                        .queryConfigByRoomIdAndGroupId(bindCsunHumidistatLocationDto.getRoomId(), loginAuthDto.getGroupId());

                // 发送配置
                if (PublicUtil.isNotEmpty(csunHumidistatConfig)) {

                    // 保存或更新设备配置
                    csunHumidistatConfig.setDeviceId(bindCsunHumidistatLocationDto.getDeviceId());
                    csunHumidistatConfig.setIsSend(LifeConstant.DEVICE_ORDER_NEED_SEND);
                    csunHumidistatConfig.setCreator(loginAuthDto.getUserName());
                    csunHumidistatConfig.setCreatorId(loginAuthDto.getUserId());
                    csunHumidistatConfig.setLastOperator(loginAuthDto.getUserName());
                    csunHumidistatConfig.setLastOperatorId(loginAuthDto.getUserId());
                    dmcCsunHumidistatConfigService.saveOrUpdate(csunHumidistatConfig);

                    gatewayMessageSender.setHumidistatTimer(bindCsunHumidistatLocationDto.getDeviceId(),
                            csunHumidistatConfig.getTemperatureMeasuringTimeInterval());
                }

                break;
        }

        DmcCsunHumidistatLocation dmcCsunHumidistatLocation = new DmcCsunHumidistatLocation();
        BeanUtils.copyProperties(bindCsunHumidistatLocationDto, dmcCsunHumidistatLocation);

        return dmcCsunHumidistatLocationMapper.insertSelective(dmcCsunHumidistatLocation);
    }

    /**
     * untied dmc csun humidistat and location
     *
     * @param deviceId the dmc csun humidistat id
     * @return the int
     */
    @Override
    public Integer untied(Long deviceId) {

        DmcCsunHumidistatLocation dmcCsunHumidistatLocation = dmcCsunHumidistatLocationMapper.selectByPrimaryKey(deviceId);

        // 解绑
        Integer result = dmcCsunHumidistatLocationMapper.deleteByPrimaryKey(deviceId);

        // TODO 删除设备配置

        // TODO 变更网关和温湿度计的绑定

        //删除阈值配置
         dmcCsunHumidistatThresholdService.deleteByKey(deviceId);
         dmcCsunHumidistatConfigService.deleteByKey(deviceId);


        // 删除温湿度计的数据
        dmcCsunHumidistatDataService.deleteByKey(deviceId);
        // 删除温湿度计历史数据
        DmcCsunHumidistatDataHi record = new DmcCsunHumidistatDataHi();
        record.setDeviceId(deviceId);
        dmcCsunHumidistatDataHiService.delete(record);

//        if (result > 0 && dmcCsunHumidistatLocation != null && dmcCsunHumidistatLocation.getBindType().equals(DeviceConstant.DEVICE_BIND_TYPE_LIFE)) {   // 删除温湿度报警
            dmcDeviceAlertService.deleteByDeviceId(deviceId);
//        }

        return result;
    }

    @Override
    public List<Long> selectDeviceIdByRoomId(Long roomId) {
        return dmcCsunHumidistatLocationMapper.selectDeviceIdByRoomId(roomId);
    }

    @Override
    public List<String> selectTemperatureByRoomId(Long roomId) {
        return dmcCsunHumidistatLocationMapper.selectTemperatureByRoomId(roomId);
    }

    @Override
    public List<lifeRoomHumidistat> selectHumidistatByRoomId(Long roomId) {
        return dmcCsunHumidistatLocationMapper.selectHumidistatByRoomId(roomId);
    }

    /**
     * get csun humidistat by device no
     *
     * @param deviceNo the device no
     * @return the csun humidistat vo
     */
    @Override
    public CsunHumidistatVo getCsunHumidistatByDeviceNo(String deviceNo) {

        CsunHumidistatQueryDto csunHumidistatQueryDto = new CsunHumidistatQueryDto();
        csunHumidistatQueryDto.setDeviceNo(deviceNo);
        csunHumidistatQueryDto.setDeviceType(DmcDeviceTypeEnum.HUMIDISTAT.getIndex());

        PageHelper.startPage(1, 1);

        List<CsunHumidistatVo> csunHumidistatVoList = dmcCsunHumidistatLocationMapper
                .queryListWithPage(csunHumidistatQueryDto);

        if (PublicUtil.isEmpty(csunHumidistatVoList)) {
            return null;
        }

        return csunHumidistatVoList.get(0);
    }

    @Override
    public DmcDeviceByRoom selectRoomIdByDeviceId(Long alertId) {
        return dmcCsunHumidistatLocationMapper.selectRoomIdByDeviceId(alertId);
    }

    @Override
    public List<CsunHumidistatVo> listGatewayBindHumidistat(Long deviceId) {

        List<CsunHumidistatVo> csunHumidistatVoList = dmcCsunHumidistatLocationMapper.listGatewayBindHumidistat(deviceId);

        for (CsunHumidistatVo chv : csunHumidistatVoList) {
            if (PublicUtil.isNotEmpty(chv.getBindType())) {

                String redisKey = RedisKeyUtil.getCsunHumidistatOnline(chv.getDeviceNo());
                String deviceNoQuery = (String) redisTemplate.opsForValue().get(redisKey);
                if (PublicUtil.isEmpty(deviceNoQuery)) {    // 温湿度计已经离线
                    chv.setStatus(DeviceStatusEnum.OFFLINE.getKey());


                } else {
                    chv.setStatus(DeviceStatusEnum.ONLINE.getKey());
                }
                chv.setBind(true);
                switch (chv.getBindType()) {
                    case DeviceConstant.DEVICE_BIND_TYPE_ROOM:
                        RoomBuildingVo vo = (RoomBuildingVo) redisTemplate
                                .opsForValue().get(RedisKeyUtil.getOmcRoomId(chv.getRoomId()));
                        if (PublicUtil.isNotEmpty(vo)) {
                            chv.setBuildingName(vo.getBuildingName());
                            chv.setFloorNo(vo.getFloorNo());
                            chv.setRoomNo(vo.getRoomNo());
                            chv.setOldmanId(vo.getOldmanId());
                            chv.setOldmanName(vo.getOldmanName());
                            chv.setLocation(vo.getRoomNo());
                        }
                        break;
                    case DeviceConstant.DEVICE_BIND_TYPE_LIFE:
                        // 根据life房间Id获取楼栋楼层房间信息
                        RoomBuildingVo roomBuildingVo = (RoomBuildingVo) redisTemplate
                                .opsForValue().get(RedisKeyUtil.getOmcRoomId(chv.getRoomId()));
                        if (PublicUtil.isNotEmpty(roomBuildingVo)) {
                            chv.setBuildingName(roomBuildingVo.getBuildingName());
                            chv.setFloorNo(roomBuildingVo.getFloorNo());
                            chv.setRoomNo(roomBuildingVo.getRoomNo());
                            chv.setOldmanId(roomBuildingVo.getOldmanId());
                            chv.setOldmanName(roomBuildingVo.getOldmanName());
                        }
                        break;
                }
            }
        }
        return csunHumidistatVoList;
    }

    @Override
    public List<PropertyDataVo> selectDeviceData(SelectDeviceDataDto selectDeviceDataDto) {
        return dmcCsunHumidistatLocationMapper.selectDeviceData(selectDeviceDataDto);
    }

    @Override
    public DmcCsunHumidistatLocation selectlocationBydeviceNo(String deviceNo) {
        return dmcCsunHumidistatLocationMapper.selectlocationBydeviceNo(deviceNo);
    }

    @Override
    public CsunHumidistatVo get(Long deviceId) {
        return dmcCsunHumidistatLocationMapper.get(deviceId);
    }

    /**
     * 根据房间Id查询温湿度计数据
     *
     * @param roomIdList the room id list
     *
     * @return the humidistat req vo list
     */
    @Override
    public List<HumidistatReqVo> queryHumidistatByRoomIds(List<Integer> roomIdList) {

        return dmcCsunHumidistatLocationMapper.queryHumidistatByRoomIds(roomIdList);
    }
}
